package errors

import (
	"fmt"
	"net/http"
)

// AppError 应用错误类型
type AppError struct {
	Code       int         `json:"code"`              // 错误码
	Message    string      `json:"message"`           // 错误消息
	Details    interface{} `json:"details,omitempty"` // 错误详情
	HttpStatus int         `json:"-"`                 // HTTP状态码
	Err        error       `json:"-"`                 // 原始错误
}

// Error 实现error接口
func (e AppError) Error() string {
	if e.Err != nil {
		return fmt.Sprintf("%s: %v", e.Message, e.Err)
	}
	return e.Message
}

// StatusCode 获取HTTP状态码
func (e AppError) StatusCode() int {
	if e.HttpStatus == 0 {
		return http.StatusInternalServerError
	}
	return e.HttpStatus
}

// ErrorCode 获取错误码
func (e AppError) ErrorCode() int {
	return e.Code
}

// WithDetails 添加详细信息
func (e AppError) WithDetails(details interface{}) AppError {
	e.Details = details
	return e
}

// Unwrap 获取原始错误
func (e AppError) Unwrap() error {
	return e.Err
}

// New 创建新的应用错误
func New(code int, message string) AppError {
	if message == "" {
		message = GetErrorMessage(code)
	}
	return AppError{
		Code:       code,
		Message:    message,
		HttpStatus: inferHttpStatus(code),
	}
}

// Wrap 包装已有错误
func Wrap(err error, code int, message string) AppError {
	if message == "" {
		message = GetErrorMessage(code)
	}
	return AppError{
		Code:       code,
		Message:    message,
		HttpStatus: inferHttpStatus(code),
		Err:        err,
	}
}

// 根据错误码推断HTTP状态码
func inferHttpStatus(code int) int {
	switch {
	case code >= 10000 && code < 20000:
		return http.StatusInternalServerError
	case code >= 20000 && code < 21000:
		if code == ErrCodeAuthentication {
			return http.StatusUnauthorized
		}
		if code == ErrCodeAuthorization {
			return http.StatusForbidden
		}
		if code == ErrCodeUserNotFound {
			return http.StatusNotFound
		}
		return http.StatusBadRequest
	case code >= 30000 && code < 40000:
		if code == ErrCodeBookNotFound {
			return http.StatusNotFound
		}
		return http.StatusBadRequest
	case code >= 40000 && code < 50000:
		if code == ErrCodeContentNotFound {
			return http.StatusNotFound
		}
		return http.StatusBadRequest
	default:
		return http.StatusInternalServerError
	}
}

// ========== 通用错误函数 ==========

// JSONFormatError 创建JSON格式错误
func JSONFormatError() AppError {
	return New(ErrCodeJsonFormat, "")
}

// ValidationErrors 创建包含多个验证错误的错误信息
func ValidationErrors(fieldErrors map[string]int) AppError {
	// 将错误码转换为错误消息
	fieldMessages := make(map[string]string)
	for field, code := range fieldErrors {
		fieldMessages[field] = GetErrorMessage(code)
	}

	return New(ErrCodeValidation, "请求参数验证失败").WithDetails(map[string]interface{}{
		"fields": fieldMessages,
	})
}
